package com.xinqi.modules.prepare.question.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.modules.prepare.common.enums.PrepareLimitEnum;
import com.xinqi.modules.prepare.question.domain.PrepareQuestionFolderRefEntity;
import com.xinqi.modules.prepare.question.dto.QuestionSortDTO;
import com.xinqi.modules.prepare.question.dto.req.PrepareQuestionFolderRefQueryDTO;
import com.xinqi.modules.prepare.question.dto.rsp.PrepareQuestionBankResultDTO;
import com.xinqi.modules.prepare.question.dto.rsp.PrepareQuestionFolderRefResultDTO;
import com.xinqi.modules.prepare.question.dto.rsp.PrepareQuestionStatsDataDTO;
import com.xinqi.modules.prepare.question.dto.rsp.QuestionTypeStatsDetail;
import com.xinqi.modules.prepare.question.manager.PrepareQuestionFolderRefManager;
import com.xinqi.modules.prepare.question.mapper.PrepareQuestionFolderRefMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 备课区试题夹关联题目管理层实现
 *
 * @author: system
 * @date: 2023/03/19
 */
@Service
@RequiredArgsConstructor
public class PrepareQuestionFolderRefManagerImpl extends BaseServiceImpl<PrepareQuestionFolderRefMapper, PrepareQuestionFolderRefEntity> implements PrepareQuestionFolderRefManager {

    /**
     * 自定义分页查询
     */
    @Override
    public Page<PrepareQuestionFolderRefResultDTO> findPage(Page<Object> page, PrepareQuestionFolderRefQueryDTO query) {
        return this.baseMapper.findPage(page, query);
    }

    @Override
    public IPage<PrepareQuestionBankResultDTO> questionPage(Page<Object> page, PrepareQuestionFolderRefQueryDTO dto) {
        return this.baseMapper.questionPage(page, dto);
    }

    @Override
    public PrepareQuestionStatsDataDTO questionStats(Long prepareId, Long questionFolderId) {
        List<QuestionTypeStatsDetail> list = this.baseMapper.questionStats(prepareId, questionFolderId);
        return PrepareQuestionStatsDataDTO.of(list);
    }

    /**
     * 自定义列表查询
     */
    @Override
    public List<PrepareQuestionFolderRefResultDTO> findList(PrepareQuestionFolderRefQueryDTO query) {
        return this.baseMapper.findList(query);
    }

    /**
     * 根据id查询 备课区试题夹关联题目数据
     */
    @Override
    public PrepareQuestionFolderRefEntity findById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return getById(id);
    }

    private boolean existByFolderAndQuestionId(Long prepareId, Long questionFolderId, Long questionId) {
        LambdaQueryWrapper<PrepareQuestionFolderRefEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PrepareQuestionFolderRefEntity::getPrepareId, prepareId);
        wrapper.eq(PrepareQuestionFolderRefEntity::getQuestionFolderId, questionFolderId);
        wrapper.eq(PrepareQuestionFolderRefEntity::getQuestionId, questionId);
        return this.baseMapper.exists(wrapper);
    }

    /**
     * 根据id删除 备课区试题夹关联题目数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        CommonErrors.BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletedByFolderIds(List<Long> folderIds) {
        LambdaQueryWrapper<PrepareQuestionFolderRefEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(PrepareQuestionFolderRefEntity::getQuestionFolderId, folderIds);
        remove(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean joinQuestionFolder(Long prepareId, Long questionFolderId, List<Long> questionIds) {
        // 限制校验
        LambdaQueryWrapper<PrepareQuestionFolderRefEntity> wrapper = new LambdaQueryWrapper<>();
        long count = count(wrapper.eq(PrepareQuestionFolderRefEntity::getQuestionFolderId, questionFolderId));
        PrepareLimitEnum.试题夹题目限制.check(count + questionIds.size());

        List<PrepareQuestionFolderRefEntity> refList = questionIds.stream()
            .filter(v -> v != null && !existByFolderAndQuestionId(prepareId, questionFolderId, v))
            .map(v -> {
                PrepareQuestionFolderRefEntity ref = new PrepareQuestionFolderRefEntity();
                ref.setPrepareId(prepareId);
                ref.setQuestionFolderId(questionFolderId);
                ref.setSort(System.currentTimeMillis()/1000L);
                ref.setQuestionId(v);
                return ref;
            }).collect(Collectors.toList());
        return saveBatch(refList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeQuestionFolder(Long prepareId, Long questionFolderId, List<Long> questionIds) {
        LambdaQueryWrapper<PrepareQuestionFolderRefEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PrepareQuestionFolderRefEntity::getPrepareId, prepareId);
        wrapper.eq(PrepareQuestionFolderRefEntity::getQuestionFolderId, questionFolderId);
        wrapper.in(PrepareQuestionFolderRefEntity::getQuestionId, questionIds);
        return remove(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sortFolderQuestion(Long prepareId, Long questionFolderId, List<QuestionSortDTO> sorts) {
        // 查询所有引用列表
        List<PrepareQuestionFolderRefEntity> list = findByFolderAndQuestionIds(prepareId, questionFolderId, sorts.stream().map(QuestionSortDTO::getId).collect(Collectors.toList()));
        // 转换map
        Map<Long, Long> sortMap = sorts.stream().collect(Collectors.toMap(QuestionSortDTO::getId, QuestionSortDTO::getSort));
        // 设置序号
        list.forEach(v -> v.setSort(sortMap.get(v.getQuestionId())));
        // 更新序号
        return updateBatchById(list);
    }

    private List<PrepareQuestionFolderRefEntity> findByFolderAndQuestionIds(Long prepareId, Long questionFolderId, List<Long> questionIds) {
        LambdaQueryWrapper<PrepareQuestionFolderRefEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PrepareQuestionFolderRefEntity::getPrepareId, prepareId);
        wrapper.eq(PrepareQuestionFolderRefEntity::getQuestionFolderId, questionFolderId);
        wrapper.in(PrepareQuestionFolderRefEntity::getQuestionId, questionIds);
        return list(wrapper);
    }

}
